//[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[[
/**
 *
 *	@file		field_demo.c
 *	@brief		フィールド上での簡単なデモ処理
 *	@author		iwasawa
 *	@data		2006.04.17〜
 *
 */
//]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]]

#include "common.h"

#include "system/swsprite.h"
#include "system/arc_util.h"
#include "system/wipe.h"
#include "system/fontproc.h"
#include "system/pm_str.h"
#include "fieldmap.h"
#include "fieldmap_work.h"
#include "fieldsys.h"
#include "motion_bl.h"
#include "field_subscreen.h"
#include "field_3dobj.h"
#include "field_light.h"
#include "field_cutin.h"

#include "system/snd_tool.h"

#include "msgdata/msg.naix"
#include "msgdata/msg_fld_demo.h"

#define	__FIELD_DEMO_H_GLOBAL
#include "field_demo.h"

//-----------------------------------------------------------------------------
/**
 *					コーディング規約
 *		●関数名
 *				１文字目は大文字それ以降は小文字にする
 *		●変数名
 *				・変数共通
 *						constには c_ を付ける
 *						staticには s_ を付ける
 *						ポインタには p_ を付ける
 *						全て合わさると csp_ となる
 *				・グローバル変数
 *						１文字目は大文字
 *				・関数内変数
 *						小文字と”＿”と数字を使用する 関数の引数もこれと同じ
*/
//-----------------------------------------------------------------------------
#ifdef PM_DEBUG
//#define FIELD_DEMO_DEBUG		// デバックタスクをまわすか？
#endif // PM_DEBUG

#ifdef FIELD_DEMO_DEBUG
static int FIELD_DEMO_DEBUG_STOP = 0;
static TCB_PTR pFieldDemoDebugTcb = NULL;
static void FieldDemoDebugTcb( TCB_PTR tcb, void* p_work );
static void FieldDemoDebugStart( void );
static void FieldDemoDebugEnd( void );
#endif // FIELD_DEMO_DEBUG


/////////////////////////////////////////////////////////////////////////////////////////////
//アサギ灯台　アカリちゃん復活イベント
/////////////////////////////////////////////////////////////////////////////////////////////

typedef struct _TOUDAI_RECOVER{
	int heapID;
	FIELDSYS_WORK *fsys;

	u16 seq;
	u16 ct;

	FLD_3DOBJ_MDL	mdl;
	FLD_3DOBJ_ANM	anm[2];
	FLD_3DOBJ		draw;
	NNSFndAllocator allocator;

	int se_count;
}TOUDAI_RECOVER;

#include "field/fld_demo.naix"

static BOOL GMEVENT_AsagiToudaiRecover( GMEVENT_CONTROL* event );
static TOUDAI_RECOVER* toudaisub_AsagiToudaiRecoverWorkInit( FIELDSYS_WORK* fsys );

static void toudaisub_ModelInit(TOUDAI_RECOVER* wk);
static void toudaisub_ModelRelease(TOUDAI_RECOVER* wk);
static void toudaisub_ModelDraw(TOUDAI_RECOVER* wk);

//----------------------------------------------------------------------------------------------
/**
 * アカリちゃん復活デモイベント呼び出し
 *
 * @param	event		イベント制御ワークへのポインタ
 *
 * @retval	none
 */
//----------------------------------------------------------------------------------------------
void EventCmd_AsagiToudaiRecoverDemo( GMEVENT_CONTROL* event )
{
	FIELDSYS_WORK* fsys	= FieldEvent_GetFieldSysWork( event );

	FieldEvent_Call( event, GMEVENT_AsagiToudaiRecover,
		toudaisub_AsagiToudaiRecoverWorkInit( fsys ));
	return;
}

#ifdef PM_DEBUG
//デバッグメニュー用イベントセットバージョン
void Debug_AsagiToudaiRecoverDemo( FIELDSYS_WORK* fsys )
{
	FieldEvent_Set( fsys, GMEVENT_AsagiToudaiRecover,
		toudaisub_AsagiToudaiRecoverWorkInit( fsys ));
}

#endif	//PM_DEBUG

//----------------------------------------------------------------------------------------------
/**
 *	@brief	灯台回復デモワーク初期化
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static TOUDAI_RECOVER* toudaisub_AsagiToudaiRecoverWorkInit( FIELDSYS_WORK* fsys )
{
	TOUDAI_RECOVER* wk;

	//システムワーク確保
	wk = sys_AllocMemory( HEAPID_FIELD, sizeof(TOUDAI_RECOVER) );
	if( wk == NULL ){
		GF_ASSERT( (0) && "灯台回復デモ メモリ確保失敗！\n" );
		return NULL;
	}
	//初期化
	MI_CpuClear8( wk, sizeof(TOUDAI_RECOVER) );
	wk->fsys	= fsys;
	wk->heapID = HEAPID_FIELD;
	return wk;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	灯台回復デモシーケンス
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static BOOL GMEVENT_AsagiToudaiRecover( GMEVENT_CONTROL* event )
{
	TOUDAI_RECOVER* wk = FieldEvent_GetSpecialWork( event );

	switch(wk->seq){
	case 0:
		toudaisub_ModelInit(wk);
		wk->ct = 0;
		wk->se_count = 0;
		wk->seq++;
		break;
	case 1:
		//SEを音程を操作しながら再生する
		if( wk->se_count != 255 ){												//一応上限チェック

			if( (wk->se_count == 0) || (wk->se_count == 30) ||
				(wk->se_count == 50) || (wk->se_count == 60) ||
				(wk->se_count == 70) || (wk->se_count == 80) ){
				Snd_SePlay( SEQ_SE_DP_FW411 );

				if( wk->se_count == 50 ){
					Snd_SePlay( SEQ_SE_DP_F207 );
				}

				//60以上で再生されるタイミングは音程を操作
				if( wk->se_count >= 60 ){
					Snd_SePitchPlay( SEQ_SE_DP_FW411, 64*(wk->se_count/10-5) );	//64*1,64*2,64*3
				}
			}

			wk->se_count++;
		}

		toudaisub_ModelDraw(wk);
		if(wk->ct++ < (30*3)){
			break;
		}
		//ホワイトアウト呼び出し
		WIPE_SYS_Start(WIPE_PATTERN_M,
			WIPE_TYPE_FADEOUT,WIPE_TYPE_FADEOUT,0x7fff,24,2,wk->heapID);
		wk->seq++;
		break;
	case 2:
		toudaisub_ModelDraw(wk);
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		wk->ct = 0;
		wk->seq++;
		break;
	case 3:
		if(wk->ct++ < 60){
			break;
		}
		//アニメ破棄
		toudaisub_ModelRelease(wk);

		// LIGHT設定変更
		DellLightCont( &wk->fsys->light_cont_data );
		wk->fsys->light_cont_data = InitLightCont( wk->fsys->glst_data, LIGHT_TYPE_TOUDAI02 );

		//ホワイトイン呼び出し
		WIPE_SYS_Start(WIPE_PATTERN_M,
			WIPE_TYPE_FADEIN,WIPE_TYPE_FADEIN,0x7fff,COMM_BRIGHTNESS_SYNC*3,1,wk->heapID);
		wk->seq++;
		break;
	case 4:
		if(!WIPE_SYS_EndCheck()){
			break;
		}
		sys_FreeMemoryEz(wk);
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief 光の環オブジェクト作成
 */
static void toudaisub_ModelInit(TOUDAI_RECOVER* wk)
{
	// アロケーター作成
	sys_InitAllocator( &wk->allocator, wk->heapID, 32 );

	//光の環モデルロード
	FLD_3DObjMdlLoad(&wk->mdl,ARC_FLD_DEMO_GRA , NARC_fld_demo_akari_ring_nsbmd, wk->heapID);

	//アニメデータロード
	FLD_3DObjAnmLoad(&wk->anm[0],&wk->mdl,ARC_FLD_DEMO_GRA,NARC_fld_demo_akari_ring_nsbca,
		wk->heapID, &wk->allocator );
	FLD_3DObjAnmLoad(&wk->anm[1],&wk->mdl,ARC_FLD_DEMO_GRA,NARC_fld_demo_akari_ring_nsbtp,
		wk->heapID, &wk->allocator );

	//描画オブジェクト初期化
	FLD_3DObjInit( &wk->draw, &wk->mdl );

	//アニメをリンク
	FLD_3DObjAddAnm( &wk->draw, &wk->anm[0] );
	FLD_3DObjAddAnm( &wk->draw, &wk->anm[1] );
	FLD_3DObjSetMatrix( &wk->draw, FX32_CONST(8*16+8), 0, FX32_CONST(10*16) );
	//描画フラグ設定
	FLD_3DObjSetDraw( &wk->draw,TRUE);
}

/**
 *	@brie	光の環オブジェクト削除
 */
static void toudaisub_ModelRelease(TOUDAI_RECOVER* wk)
{
	//描画フラグ設定
	FLD_3DObjSetDraw( &wk->draw,FALSE);
	//アニメデータ破棄
	FLD_3DObjAnmDelete( &wk->anm[1], &wk->allocator);
	FLD_3DObjAnmDelete( &wk->anm[0], &wk->allocator);
	//モデルデータ破棄
	FLD_3DObjMdlDelete( &wk->mdl);
}

/**
 *	@brief	光の環オブジェクト再生メイン
 */
static void toudaisub_ModelDraw(TOUDAI_RECOVER* wk)
{
	FLD_3DObjAnmLoop( &wk->anm[0],FX32_ONE);
	FLD_3DObjAnmLoop( &wk->anm[1],FX32_ONE);
	FLD_3DObjDraw( &wk->draw );
}

/////////////////////////////////////////////////////////////////////////////////////////////
//field_demo内汎用　アニメ再生ユーティリティ
/////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _FDEMO_OBJ{
	FLD_3DOBJ_MDL	mdl;
	FLD_3DOBJ		draw;
	FLD_3DOBJ_ANM	*anm;
	NNSFndAllocator	allocator;

	u8				anm_num;
	u16				frame;	//アニメ再生スピード
	int				heapID;
}FDEMO_OBJ;

typedef struct _FDEMO_OBJ_RES{
	u16	arcID;
	u8	mdl_idx;
	u8	anm_num;
	const u16* anmTbl;
}FDEMO_OBJ_RES;


static FDEMO_OBJ* FDemoObj_AllocInit(const FDEMO_OBJ_RES* res,int heapID);
static void FDemoObj_Free(FDEMO_OBJ* obj);
static void FDemoObj_AnmDataRebind(FDEMO_OBJ* obj,u32 arcID,const u16* anm_tbl,u8 anm_num);
static BOOL FDemoObj_Draw(FDEMO_OBJ* obj);

static FDEMO_OBJ* FDemoObj_AllocInit(const FDEMO_OBJ_RES* res,int heapID)
{
	FDEMO_OBJ* obj;
	int i;

	obj = sys_AllocMemory(heapID,sizeof(FDEMO_OBJ));
	MI_CpuClear8(obj,sizeof(FDEMO_OBJ));

	obj->heapID = heapID;

	// アロケーター作成
	sys_InitAllocator( &obj->allocator, heapID, 32 );

	//モデル読み込み
	FLD_3DObjMdlLoad(&obj->mdl,res->arcID , res->mdl_idx, heapID);

	//描画オブジェクト初期化
	FLD_3DObjInit(&obj->draw,&obj->mdl);

	//アニメ読み込み
	FDemoObj_AnmDataRebind(obj,res->arcID,res->anmTbl,res->anm_num);

	//描画フラグ設定
	FLD_3DObjSetDraw( &obj->draw,TRUE);

	obj->frame = 1;	//デフォは再生スピード1
	return obj;
}

/**
 *	@brief	フィールドデモ用オブジェクト　フリー
 */
static void FDemoObj_Free(FDEMO_OBJ* obj)
{
	int i;

	//描画フラグ設定
	FLD_3DObjSetDraw( &obj->draw,FALSE);

	//アニメデータ破棄
	for(i = 0;i < obj->anm_num;i++){
		FLD_3DObjRemoveAnm( &obj->draw, &obj->anm[i]);
		FLD_3DObjAnmDelete(&obj->anm[i],&obj->allocator);
	}
	obj->anm_num = 0;

	//モデルデータ破棄
	FLD_3DObjMdlDelete(&obj->mdl);

	//メモリ破棄
	sys_FreeMemoryEz(obj->anm);
	sys_FreeMemoryEz(obj);
	obj = NULL;
}

/*
 *	@brief	アニメデータセットリバインド
 */
static void FDemoObj_AnmDataRebind(FDEMO_OBJ* obj,u32 arcID,const u16* anm_tbl,u8 anm_num)
{
	int i;

	if(obj->anm_num){
		for(i = 0;i < obj->anm_num;i++){
			FLD_3DObjRemoveAnm( &obj->draw, &obj->anm[i]);
			FLD_3DObjAnmDelete(&obj->anm[i],&obj->allocator);
		}
		sys_FreeMemoryEz(obj->anm);
	}

	obj->anm_num = anm_num;
	obj->anm = sys_AllocMemory(obj->heapID,sizeof(FLD_3DOBJ_ANM)*obj->anm_num);
	MI_CpuClear8(obj->anm,sizeof(FLD_3DOBJ_ANM)*obj->anm_num);
	for(i = 0;i < obj->anm_num;i++)	{
		FLD_3DObjAnmLoad(&obj->anm[i],&obj->mdl,arcID,anm_tbl[i],obj->heapID, &obj->allocator );
		FLD_3DObjAddAnm(&obj->draw,&obj->anm[i]);
	}
}

/**
 *	@brief	フィールドデモ用オブジェクト　描画再生
 *
 *	@retval	TRUE 再生終了
 *	@retval	FALSE 再生中
 */
static BOOL FDemoObj_Draw(FDEMO_OBJ* obj)
{
	int i;
	int anm_f = 0;

	for(i = 0;i < obj->anm_num;i++){
		anm_f += FLD_3DObjAnmNoLoop(&obj->anm[i],FX32_CONST(obj->frame));
	}
	FLD_3DObjDraw( &obj->draw );

	if(anm_f == obj->anm_num){
		return TRUE;
	}
	return FALSE;
}

/**
 *	@brief	フィールドデモ用オブジェクト　ループ再生
 */
static void FDemoObj_DrawLoop(FDEMO_OBJ* obj)
{
	int i;

	for(i = 0;i < obj->anm_num;i++){
		FLD_3DObjAnmLoop(&obj->anm[i],FX32_CONST(obj->frame));
	}
	FLD_3DObjDraw( &obj->draw );
}

/////////////////////////////////////////////////////////////////////////////////////////////
//プレイヤー　足元エフェクト
//＊アジト ポケモン床エフェクトetc
/////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _PLAYER_POS_EFF{
	int	heapID;
	FIELDSYS_WORK* fsys;
	FDEMO_OBJ* obj;
	u16	seq;
	u16	ct;
	u16	pat;
}PLAYER_POS_EFF;

typedef struct _PLAYER_POS_EFF_RES{
	FDEMO_OBJ_RES	obj_res;
	u16	se_no;
}PLAYER_POS_EFF_RES;

static PLAYER_POS_EFF* ppeffsub_WorkInit( FIELDSYS_WORK* fsys ,u8 pat);
static BOOL GMEVENT_PlayerPosEffect( GMEVENT_CONTROL* event );

static const u16 DATA_AjitoPokeF_ThunderAnm[] = {
	NARC_fld_demo_asito_thunder_nsbca,
};
static const u16 DATA_AjitoPokeF_PoisonAnm[] = {
	NARC_fld_demo_asito_poison_nsbca,
	NARC_fld_demo_asito_poison_nsbma,
};
static const u16 DATA_AjitoPokeF_RockAnm[] = {
	NARC_fld_demo_asito_rock_nsbca,
	NARC_fld_demo_asito_rock_nsbma,
	NARC_fld_demo_asito_rock_nsbta,
};
static const PLAYER_POS_EFF_RES DATA_PlayerPosEffectTbl[] = {
 {	//アジト　ポケモン床 雷
	 {	ARC_FLD_DEMO_GRA, NARC_fld_demo_asito_thunder_nsbmd,
		1,DATA_AjitoPokeF_ThunderAnm
	 },
	 SEQ_SE_GS_DENKI_TRAP,
 },
 {	//アジト　ポケモン床 毒
	 {	ARC_FLD_DEMO_GRA, NARC_fld_demo_asito_poison_nsbmd,
		2,DATA_AjitoPokeF_PoisonAnm
	 },
	 SEQ_SE_GS_DOKU_TRAP,
 },
 {	//アジト　ポケモン床 岩
	 {	ARC_FLD_DEMO_GRA, NARC_fld_demo_asito_rock_nsbmd,
		3,DATA_AjitoPokeF_RockAnm
	 },
	 SEQ_SE_GS_IWA_TRAP,
 },
};

//----------------------------------------------------------------------------------------------
/**
 * プレイヤ足元エフェクト再生イベント呼び出し
 *
 * @param	event		イベント制御ワークへのポインタ
 * @param	no			再生パターンナンバー
 *
 * @retval	none
 */
//----------------------------------------------------------------------------------------------
void EventCmd_PlayerPosEffect( GMEVENT_CONTROL* event ,u8 no)
{
	FIELDSYS_WORK* fsys	= FieldEvent_GetFieldSysWork( event );

	FieldEvent_Call( event, GMEVENT_PlayerPosEffect, ppeffsub_WorkInit( fsys , no));
	return;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	プレイヤー足元エフェクトワーク初期化
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static PLAYER_POS_EFF* ppeffsub_WorkInit( FIELDSYS_WORK* fsys ,u8 pat)
{
	PLAYER_POS_EFF* wk;

	//システムワーク確保
	wk = sys_AllocMemory( HEAPID_FIELD, sizeof(PLAYER_POS_EFF) );
	if( wk == NULL ){
		GF_ASSERT_MSG(0,"プレイヤー足元エフェクト再生 %d メモリ確保失敗！\n",pat);
		return NULL;
	}
	//初期化
	MI_CpuClear8( wk, sizeof(PLAYER_POS_EFF) );
	wk->fsys	= fsys;
	wk->pat = pat;
	wk->heapID = HEAPID_FIELD;
	return wk;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	プレイヤー足元エフェクト再生シーケンス
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static BOOL GMEVENT_PlayerPosEffect( GMEVENT_CONTROL* event )
{
	PLAYER_POS_EFF* wk = FieldEvent_GetSpecialWork( event );

	switch(wk->seq){
	case 0:
		wk->obj = FDemoObj_AllocInit(&DATA_PlayerPosEffectTbl[wk->pat].obj_res,wk->heapID);
		{
			VecFx32 vec;
			Player_VecPosGet(wk->fsys->player, &vec);
			FLD_3DObjSetMatrix( &wk->obj->draw, vec.x, vec.y, vec.z );
			Snd_SePlay(DATA_PlayerPosEffectTbl[wk->pat].se_no);
		}
		wk->seq++;
		break;
	case 1:
		if(!FDemoObj_Draw(wk->obj)){
			break;
		}
		wk->seq++;
		break;
	case 2:
		//アニメ破棄
		FDemoObj_Free(wk->obj);
		sys_FreeMemoryEz(wk);
		return TRUE;
	}
	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////////////////////
//虹色の羽根　銀の羽根エフェクト
/////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _LEGEND_FEATHER_EFF{
	int	heapID;
	FIELDSYS_WORK* fsys;
	FDEMO_OBJ* obj;
	TCB_PTR	p_tcb;
	u8	ver;
	u8	end_f;
	u16	seq;
	u16	ct;
}LEGEND_FEATHER_EFF;

typedef struct _LEGEND_FEATHER_TASKWK{
	FDEMO_OBJ*	obj;
}LEGEND_FEATHER_TASKWK;

#include "fielddata/script/d17r0101_def.h"
#include "fielddata/script/d40r0104_def.h"

static LEGEND_FEATHER_EFF* lfeffsub_WorkInit( FIELDSYS_WORK* fsys ,u8 ver);
static BOOL GMEVENT_LegendFeatherEffect( GMEVENT_CONTROL* event );
static void tcb_FeatherEff( TCB_PTR tcb, void* p_work );

static const u16 DATA_FeatherEff_HououAnm01[] = {
	NARC_fld_demo_ef_strb1_nsbca,
	NARC_fld_demo_ef_strb1_nsbma,
	NARC_fld_demo_ef_strb1_nsbtp,
};
static const u16 DATA_FeatherEff_HououAnm02[] = {
	NARC_fld_demo_ef_strb2_nsbca,
	NARC_fld_demo_ef_strb2_nsbma,
	NARC_fld_demo_ef_strb2_nsbtp,
};
static const u16 DATA_FeatherEff_HououAnm03[] = {
	NARC_fld_demo_ef_strb3_nsbca,
	NARC_fld_demo_ef_strb3_nsbma,
	NARC_fld_demo_ef_strb3_nsbtp,
};
static const u16 DATA_FeatherEff_RugiaAnm01[] = {
	NARC_fld_demo_ef_stsv1_nsbca,
	NARC_fld_demo_ef_stsv1_nsbma,
	NARC_fld_demo_ef_stsv1_nsbtp,
};
static const u16 DATA_FeatherEff_RugiaAnm02[] = {
	NARC_fld_demo_ef_stsv2_nsbca,
	NARC_fld_demo_ef_stsv2_nsbma,
	NARC_fld_demo_ef_stsv2_nsbtp,
};
static const u16 DATA_FeatherEff_RugiaAnm03[] = {
	NARC_fld_demo_ef_stsv3_nsbca,
	NARC_fld_demo_ef_stsv3_nsbma,
	NARC_fld_demo_ef_stsv3_nsbtp,
};

static const u16* DATA_FeatherEffAnm[][2] = {
 {
	 DATA_FeatherEff_HououAnm02,
	 DATA_FeatherEff_HououAnm03,
 },
 {
	 DATA_FeatherEff_RugiaAnm02,
	 DATA_FeatherEff_RugiaAnm03,
 },
};

#define FEATHER_EFFECT_ANMNUM	(3)
static const FDEMO_OBJ_RES DATA_FeatherEffectObjTbl[] = {
 {	ARC_FLD_DEMO_GRA, NARC_fld_demo_ef_strb1_nsbmd,
	FEATHER_EFFECT_ANMNUM,DATA_FeatherEff_HououAnm01
 },
 {	ARC_FLD_DEMO_GRA, NARC_fld_demo_ef_stsv1_nsbmd,
	FEATHER_EFFECT_ANMNUM,DATA_FeatherEff_RugiaAnm01
 },
};

//----------------------------------------------------------------------------------------------
/**
 * 伝説の羽根エフェクト再生イベント呼び出し
 *
 * @param	event		イベント制御ワークへのポインタ
 * @param	no			再生パターンナンバー
 *
 * @retval	none
 */
//----------------------------------------------------------------------------------------------
void EventCmd_LegendFeatherEffect( GMEVENT_CONTROL* event ,u8 no)
{
	FIELDSYS_WORK* fsys	= FieldEvent_GetFieldSysWork( event );

	FieldEvent_Call( event, GMEVENT_LegendFeatherEffect, lfeffsub_WorkInit( fsys , no));
	return;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	伝説の羽根エフェクトワーク初期化
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static LEGEND_FEATHER_EFF* lfeffsub_WorkInit( FIELDSYS_WORK* fsys ,u8 ver)
{
	LEGEND_FEATHER_EFF* wk;

	//システムワーク確保
	wk = sys_AllocMemory( HEAPID_FIELD, sizeof(LEGEND_FEATHER_EFF) );
	if( wk == NULL ){
		GF_ASSERT_MSG(0,"フェザーエフェクト再生 %d メモリ確保失敗！\n",ver);
		return NULL;
	}
	//初期化
	MI_CpuClear8( wk, sizeof(LEGEND_FEATHER_EFF) );
	wk->fsys	= fsys;
	wk->ver = ver;
	wk->heapID = HEAPID_FIELD;
	return wk;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	伝説の羽根エフェクト再生シーケンス
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static BOOL GMEVENT_LegendFeatherEffect( GMEVENT_CONTROL* event )
{
	LEGEND_FEATHER_EFF* wk = FieldEvent_GetSpecialWork( event );

	switch(wk->seq){
	case 0:
		wk->obj = FDemoObj_AllocInit(&DATA_FeatherEffectObjTbl[wk->ver],wk->heapID);
		{
			VecFx32 vec;
			Player_VecPosGet(wk->fsys->player, &vec);
			FLD_3DObjSetMatrix( &wk->obj->draw, vec.x, vec.y, vec.z );
			Snd_SePlay(SEQ_SE_GS_STOPPERKAIJO);
		}
		wk->seq++;
		break;
	case 1:
		if(!FDemoObj_Draw(wk->obj)){
			break;
		}
		FDemoObj_AnmDataRebind(wk->obj,ARC_FLD_DEMO_GRA,
			DATA_FeatherEffAnm[wk->ver][0],FEATHER_EFFECT_ANMNUM);

		//アニメタスク追加
		wk->p_tcb = TCB_Add( tcb_FeatherEff, wk, 0);

		//スクリプト起動
		if(wk->ver == 0){
			EventCall_Script( event, SCRID_D17R0101_BOZU_01_GOLD_FEATHER_DEMO, NULL, NULL);
		}else{
			EventCall_Script( event, SCRID_D40R0104_BOZU_01_SILVER_FEATHER_DEMO, NULL, NULL);
		}
		wk->seq++;
		break;
	case 2:
		TCB_Delete( wk->p_tcb );
		wk->seq++;
		//スルー
	case 3:
		//今のアニメの終了フレームまで待つ
		if(!FDemoObj_Draw(wk->obj)){
			break;
		}
		FDemoObj_AnmDataRebind(wk->obj,ARC_FLD_DEMO_GRA,
			DATA_FeatherEffAnm[wk->ver][1],FEATHER_EFFECT_ANMNUM);
		wk->seq++;
		//スルー
	case 4:
		if(!FDemoObj_Draw(wk->obj)){
			break;
		}
		//アニメ破棄
		FDemoObj_Free(wk->obj);
		sys_FreeMemoryEz(wk);
		return TRUE;
	}
	return FALSE;
}
/**
 *	@brief	羽根エフェクト
 */
static void tcb_FeatherEff( TCB_PTR tcb, void* p_work )
{
	FDemoObj_DrawLoop(((LEGEND_FEATHER_EFF*)(p_work))->obj);
}

/////////////////////////////////////////////////////////////////////////////////////////////
//ロケット団アジト　警報エフェクト
/////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _AJITO_ALARM_EFF{
	int	heapID;
	FIELDSYS_WORK* fsys;
	u8	seq;
	u8	sub_seq;
	u8	ct,wait,loop;
	u8	ev1;
	u8	bg0_pri;
	u8	bg1_pri;
}AJITO_ALARM_EFF;

#define AJITO_ALRAM_CGX_SIZ	(0x20*2)
#define AJITO_ALARM_ALPHA_1ST	(GX_BLEND_PLANEMASK_BG1)
#define AJITO_ALARM_ALPHA_2ND	(GX_BLEND_PLANEMASK_BG0|GX_BLEND_PLANEMASK_BG2)
#define AJITO_ALARM_ALPHA_S	(0)

static AJITO_ALARM_EFF* alarmsub_WorkInit( FIELDSYS_WORK* fsys );
static BOOL GMEVENT_AjitoAlarmEffct( GMEVENT_CONTROL* event );
static void alarmsub_ResInit( AJITO_ALARM_EFF* wk);
static void alarmsub_ResRelease( AJITO_ALARM_EFF* wk);
static BOOL alarmsub_AlarmSub( AJITO_ALARM_EFF* wk);

//----------------------------------------------------------------------------------------------
/**
 * アジト警報エフェクト再生イベント呼び出し
 *
 * @param	event		イベント制御ワークへのポインタ
 * @param	no			再生パターンナンバー
 *
 * @retval	none
 */
//----------------------------------------------------------------------------------------------
void EventCmd_AjitoAlarmEffect( GMEVENT_CONTROL* event )
{
	FIELDSYS_WORK* fsys	= FieldEvent_GetFieldSysWork( event );

	FieldEvent_Call( event, GMEVENT_AjitoAlarmEffct, alarmsub_WorkInit( fsys ));
	return;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	ロケット団アジト警報エフェクトワーク初期化
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static AJITO_ALARM_EFF* alarmsub_WorkInit( FIELDSYS_WORK* fsys )
{
	AJITO_ALARM_EFF* wk;

	//システムワーク確保
	wk = sys_AllocMemory( HEAPID_FIELD, sizeof(AJITO_ALARM_EFF) );
	if( wk == NULL ){
		GF_ASSERT_MSG(0,"警報エフェクト再生 メモリ確保失敗！\n");
		return NULL;
	}
	//初期化
	MI_CpuClear8( wk, sizeof(AJITO_ALARM_EFF) );
	wk->fsys	= fsys;
	wk->heapID = HEAPID_FIELD;
	return wk;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	アジト警報エフェクト再生シーケンス
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static BOOL GMEVENT_AjitoAlarmEffct( GMEVENT_CONTROL* event )
{
	AJITO_ALARM_EFF* wk = FieldEvent_GetSpecialWork( event );

	switch(wk->seq){
	case 0:
		alarmsub_ResInit( wk );
		Snd_SePlay(SEQ_SE_GS_AJITO_SIREN);
		wk->seq++;
		break;
	case 1:
		if(!alarmsub_AlarmSub( wk )){
			break;
		}
		if(wk->loop++ < 1){
			break;
		}
		wk->seq++;
		break;
	case 2:
		if(Snd_SePlayCheck( SEQ_SE_GS_AJITO_SIREN )){
			break;
		}
		//アニメ破棄
		alarmsub_ResRelease( wk );
		sys_FreeMemoryEz(wk);
		return TRUE;
	}
	return FALSE;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	アジト警報エフェクト リソース初期化
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static void alarmsub_ResInit( AJITO_ALARM_EFF* wk)
{
	ARCHANDLE* handle;

	//アルファ値設定
	wk->ev1 = AJITO_ALARM_ALPHA_S;
	G2_SetBlendAlpha(AJITO_ALARM_ALPHA_1ST,AJITO_ALARM_ALPHA_2ND,wk->ev1,31-wk->ev1);

	//アーカイブのハンドルを取得
	handle = ArchiveDataHandleOpen(ARC_FLD_DEMO_GRA,wk->heapID);

	// BGパレット転送
	ArcUtil_HDL_PalSet( handle,
			NARC_fld_demo_alarm_bg_nclr, PALTYPE_MAIN_BG, 0, 0x20, wk->heapID );

	//画面背景転送
	ArcUtil_HDL_BgCharSet( handle,
			NARC_fld_demo_alarm_bg_ncgr, wk->fsys->bgl, FLD_MBGFRM_EFFECT1,
			0, AJITO_ALRAM_CGX_SIZ, FALSE, wk->heapID);

	ArcUtil_HDL_ScrnSet( handle,
			NARC_fld_demo_alarm_bg_nscr, wk->fsys->bgl, FLD_MBGFRM_EFFECT1, 0, 0, FALSE, wk->heapID);


	wk->bg0_pri = GF_BGL_PriorityGet( wk->fsys->bgl, FLD_MBGFRM_MAP);
	wk->bg1_pri = GF_BGL_PriorityGet( wk->fsys->bgl, FLD_MBGFRM_EFFECT1);
	GF_BGL_PrioritySet( FLD_MBGFRM_MAP,1);
	GF_BGL_PrioritySet( FLD_MBGFRM_EFFECT1,0);
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG1, VISIBLE_ON );

	//ハンドル解放
	ArchiveDataHandleClose( handle );
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	アジト警報エフェクト リソース解放
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static void alarmsub_ResRelease( AJITO_ALARM_EFF* wk)
{
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG1, VISIBLE_OFF );
	GF_BGL_PrioritySet( FLD_MBGFRM_MAP,wk->bg0_pri);
	GF_BGL_PrioritySet( FLD_MBGFRM_EFFECT1,wk->bg1_pri);

	//スクリーンクリア
	GF_BGL_ScrClear( wk->fsys->bgl, FLD_MBGFRM_EFFECT1 );
	GF_BGL_ClearCharSet( FLD_MBGFRM_EFFECT1, AJITO_ALRAM_CGX_SIZ, 0, wk->heapID );

	G2_SetBlendAlpha(GX_BLEND_PLANEMASK_NONE,GX_BLEND_PLANEMASK_NONE,31,0);
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	アジト警報エフェクト 明滅エフェクトサブ
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static BOOL alarmsub_AlarmSub( AJITO_ALARM_EFF* wk)
{
	switch(wk->sub_seq){
	case 0:
		wk->wait = 0;
		wk->ct = 0;
		wk->ev1 = AJITO_ALARM_ALPHA_S;
		wk->sub_seq++;
		break;
	case 1:
		if(wk->wait++){
			break;
		}
		G2_SetBlendAlpha(AJITO_ALARM_ALPHA_1ST,AJITO_ALARM_ALPHA_2ND,wk->ev1,31-wk->ev1);
		if(wk->ct++ < 12){
			wk->ev1++;
		}else{
			wk->ev1--;
		}
		wk->wait = 0;
		if(wk->ct > 24){
			wk->sub_seq++;
		}
		break;
	default:
		wk->ct = 0;
		wk->wait = 0;
		wk->sub_seq = 0;
		return TRUE;
	}
	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////////////////////
//画面揺らし
/////////////////////////////////////////////////////////////////////////////////////////////

typedef struct _FDEMO_SHAKE{
	int heapID;
	FIELDSYS_WORK* fsys;

	s16	width,height;
	u16	ct,s_count;
	u16	wait,s_wait;
	fx32	akey;

	GF_CAMERA_PTR camera;		// カメラ構造体
	GF_CAMERA_PTR p_fld_camera;	// フィールドで使用されているカメラ構造体
	VecFx32 target;
	VecFx32 def_mat;

}FDEMO_SHAKE;

/**
 *	@brief	画面ゆれ共通処理　初期化
 */
static FDEMO_SHAKE* FDemoShake_AllocInit(FIELDSYS_WORK* fsys,int heapID)
{
	FDEMO_SHAKE* ps;

	ps = sys_AllocMemory(heapID,sizeof(FDEMO_SHAKE));
	MI_CpuClear8(ps,sizeof(FDEMO_SHAKE));

	ps->heapID = heapID;
	ps->fsys = fsys;

	//カメラ作成
	ps->camera = GFC_AllocCamera(heapID);

	return ps;
}

/**
 *	@brief	フィールドデモ　画面ゆれ　ワーク解放
 */
static void FDemoShake_Free(FDEMO_SHAKE* ps)
{
	//カメラ破棄
	GFC_FreeCamera(ps->camera);
	sys_FreeMemoryEz(ps);
}

/**
 *	@brief	フィールドデモ　画面ゆれ　動作開始
 */
static void FDemoShake_Start(FDEMO_SHAKE* ps,
	s16 width,s16 height,u16 s_count,u16 wait)
{
	//パラメータ初期化
	ps->width = FX32_CONST(width);
	ps->height = FX32_CONST(height);
	ps->s_count = s_count;
	ps->s_wait = wait;

	ps->wait = 0;

	ps->akey = FX_Div(FX32_CONST(360),FX32_CONST(ps->s_wait));

	//フィールドのカメラパラメータをコピー
	GFC_CopyCamera( ps->fsys->camera_ptr, ps->camera );

	// 現在のターゲット座標取得
	ps->target = GFC_GetLookTarget( ps->camera );
	ps->def_mat = ps->target;

	// ターゲット座標バインド
	GFC_BindCameraTarget( &ps->target, ps->camera );
	// カメラを有効化
	GFC_AttachCamera( ps->camera );
}

/**
 *	@brief	フィールドデモ　画面ゆれ　終了
 */
static void FDemoShake_End(FDEMO_SHAKE* ps)
{
	ps->wait = 0;

	//カメラを元に戻す
	GFC_AttachCamera(ps->fsys->camera_ptr);
}

/**
 *	@brief	フィールドデモ　画面ゆれ　メイン
 */
static BOOL FDemoShake_Main(FDEMO_SHAKE* ps)
{
	fx32 r;

	r = Sin360FX(FX_Mul(ps->akey,FX32_CONST(ps->wait++)));
	ps->target.x = FX_Mul(r,ps->width)+ps->def_mat.x;
	ps->target.y = FX_Mul(r,ps->height)+ps->def_mat.y;

	if(ps->wait < ps->s_wait){
		return FALSE;
	}
	ps->target.x = ps->def_mat.x;
	ps->target.y = ps->def_mat.y;
	ps->wait = 0;
	if(--ps->s_count > 0){
		return FALSE;
	}
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////////////////
//画面ゆれエフェクト
/////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _ZISHIN_EFF{
	int	heapID;
	FIELDSYS_WORK* fsys;

	FDEMO_SHAKE* ps;
}ZISHIN_EFF;

static ZISHIN_EFF* zishinsub_WorkInit( FIELDSYS_WORK* fsys,
	u16 width,u16 height,u16 count,u16 wait);
static BOOL GMEVENT_ZishinEffct( GMEVENT_CONTROL* event );

//----------------------------------------------------------------------------------------------
/**
 * 画面ゆれエフェクトイベント呼び出し
 *
 * @param	event		イベント制御ワークへのポインタ
 * @param	no			再生パターンナンバー
 *
 * @retval	none
 */
//----------------------------------------------------------------------------------------------
void EventCmd_ZishinEffect( GMEVENT_CONTROL* event ,
	u16 width,u16 height,u16 count,u16 wait)
{
	FIELDSYS_WORK* fsys	= FieldEvent_GetFieldSysWork( event );

	FieldEvent_Call( event, GMEVENT_ZishinEffct,
		zishinsub_WorkInit( fsys, width, height, count, wait));
	return;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	画面ゆれエフェクトワーク初期化
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static ZISHIN_EFF* zishinsub_WorkInit( FIELDSYS_WORK* fsys,
	u16 width,u16 height,u16 count,u16 wait)
{
	ZISHIN_EFF* wk;

	//システムワーク確保
	wk = sys_AllocMemory( HEAPID_FIELD, sizeof(ZISHIN_EFF) );
	if( wk == NULL ){
		GF_ASSERT_MSG(0,"地震エフェクト再生 メモリ確保失敗！\n");
		return NULL;
	}
	//初期化
	MI_CpuClear8( wk, sizeof(ZISHIN_EFF) );
	wk->fsys	= fsys;
	wk->heapID = HEAPID_FIELD;

	wk->ps = FDemoShake_AllocInit(wk->fsys,wk->heapID);
	FDemoShake_Start(wk->ps,width,height,count,wait);
	return wk;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	画面ゆれエフェクト再生シーケンス
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static BOOL GMEVENT_ZishinEffct( GMEVENT_CONTROL* event )
{
	ZISHIN_EFF* wk = FieldEvent_GetSpecialWork( event );

	if(!FDemoShake_Main(wk->ps)){
		return FALSE;
	}
	FDemoShake_End(wk->ps);
	FDemoShake_Free(wk->ps);

	sys_FreeMemoryEz(wk);
	return TRUE;
}

/////////////////////////////////////////////////////////////////////////////////////////////
//アンノーン文字ウィンドウ　表示
/////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _AN_FONT_WIN{
	int	heapID;
	FIELDSYS_WORK* fsys;
	GF_BGL_BMPWIN win;
	u8	seq;
	u8	no;
	u8	bg_pri;
}AN_FONT_WIN;


#define ALF_WIN_CGX_SIZ	(32*4)
#define ALF_WIN_PAL		(0)
#define ALF_FCOL_BASE	(9)
#define ALF_FONT_COL	GF_PRINTCOLOR_MAKE(15,14,ALF_FCOL_BASE)

#define	BMP_AN_WIN_PX	( 9 )
#define	BMP_AN_WIN_PY	( 10 )
#define	BMP_AN_WIN_SX	( 14 )
#define	BMP_AN_WIN_SY	( 2 )
#define BMP_AN_WIN_FRM	( FLD_MBGFRM_EFFECT1 )
#define	BMP_AN_WIN_PAL	( ALF_WIN_PAL )
#define	BMP_AN_WIN_CGX	( ALF_WIN_CGX_SIZ )

static AN_FONT_WIN* afwsub_WorkInit( FIELDSYS_WORK* fsys ,u8 no);
static BOOL GMEVENT_AnnoonFontWindow( GMEVENT_CONTROL* event );
static void afwsub_ResInit( AN_FONT_WIN* wk);
static void afwsub_ResRelease( AN_FONT_WIN* wk);
static BOOL afwsub_InputSub( AN_FONT_WIN* wk);

//----------------------------------------------------------------------------------------------
/**
 * アンノーン文字ウィンドウウィンドウ再生イベント呼び出し
 *
 * @param	event		イベント制御ワークへのポインタ
 * @param	no			再生パターンナンバー
 *
 * @retval	none
 */
//----------------------------------------------------------------------------------------------
void EventCmd_AnnoonFontWindow( GMEVENT_CONTROL* event , int no)
{
	FIELDSYS_WORK* fsys	= FieldEvent_GetFieldSysWork( event );

	FieldEvent_Call( event, GMEVENT_AnnoonFontWindow, afwsub_WorkInit( fsys ,no ));
	return;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	アンノーン文字ウィンドウワーク初期化
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static AN_FONT_WIN* afwsub_WorkInit( FIELDSYS_WORK* fsys, u8 no)
{
	AN_FONT_WIN* wk;

	//システムワーク確保
	wk = sys_AllocMemory( HEAPID_FIELD, sizeof(AN_FONT_WIN) );
	if( wk == NULL ){
		GF_ASSERT_MSG(0,"アンノーン文字ウィンドウ メモリ確保失敗！\n");
		return NULL;
	}
	//初期化
	MI_CpuClear8( wk, sizeof(AN_FONT_WIN) );
	wk->fsys	= fsys;
	wk->no		= no;
	wk->heapID = HEAPID_FIELD;
	return wk;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	アンノーン文字ウィンドウ再生シーケンス
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static BOOL GMEVENT_AnnoonFontWindow( GMEVENT_CONTROL* event )
{
	AN_FONT_WIN* wk = FieldEvent_GetSpecialWork( event );

	switch(wk->seq){
	case 0:
		afwsub_ResInit( wk );
		Snd_SePlay(SEQ_SE_DP_SELECT);
		wk->seq++;
		break;
	case 1:
		if(!afwsub_InputSub( wk )){
			break;
		}
		Snd_SePlay(SEQ_SE_DP_SELECT);
		wk->seq++;
		//リソース破棄
		afwsub_ResRelease( wk );
		sys_FreeMemoryEz(wk);
		return TRUE;
	}
	return FALSE;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	アンノーン文字ウィンドウ リソース初期化
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static void afwsub_ResInit( AN_FONT_WIN* wk)
{
	ARCHANDLE* handle;

	//アーカイブのハンドルを取得
	handle = ArchiveDataHandleOpen(ARC_FLD_DEMO_GRA,wk->heapID);

	// BGパレット転送
	ArcUtil_HDL_PalSet( handle,
			NARC_fld_demo_alf_win_nclr, PALTYPE_MAIN_BG, ALF_WIN_PAL, 0x20, wk->heapID );

	//画面背景転送
	ArcUtil_HDL_BgCharSet( handle,
			NARC_fld_demo_alf_win_ncgr, wk->fsys->bgl, FLD_MBGFRM_EFFECT1,
			0, 0, FALSE, wk->heapID);

	ArcUtil_HDL_ScrnSet( handle,
			NARC_fld_demo_alf_win_nscr, wk->fsys->bgl, FLD_MBGFRM_EFFECT1, 0, 0, FALSE, wk->heapID);

	wk->bg_pri = GF_BGL_PriorityGet( wk->fsys->bgl, FLD_MBGFRM_EFFECT1);
	GF_BGL_PrioritySet( FLD_MBGFRM_EFFECT1, 0);
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG1, VISIBLE_ON );

	//ハンドル解放
	ArchiveDataHandleClose( handle );

	//ウィンドウ初期化
	{
		MSGDATA_MANAGER*	man;
		STRBUF* str;
		u8	siz;
		static const BMPWIN_DAT BmpWinData = {
			BMP_AN_WIN_FRM, BMP_AN_WIN_PX, BMP_AN_WIN_PY,
			BMP_AN_WIN_SX, BMP_AN_WIN_SY, BMP_AN_WIN_PAL, BMP_AN_WIN_CGX
		};
		GF_BGL_BmpWinAddEx( wk->fsys->bgl, &wk->win, &BmpWinData );
		GF_BGL_BmpWinDataFill( &wk->win, ALF_FCOL_BASE );

		man = MSGMAN_Create(MSGMAN_TYPE_NORMAL,ARC_MSG,
							NARC_msg_fld_demo_dat,wk->heapID);
		str = MSGMAN_AllocString(man,msg_alf_win01+wk->no);

		siz = FontProc_GetPrintStrWidth( FONT_UNKNOWN, str, 0 );
		GF_STR_PrintColor( &wk->win, FONT_UNKNOWN, str,
			((BMP_AN_WIN_SX*8)-siz)/2,0, MSG_NO_PUT, ALF_FONT_COL, NULL );

		GF_BGL_BmpWinOnVReq(&wk->win);

		STRBUF_Delete(str);
		MSGMAN_Delete(man);
	}

}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	アンノーン文字ウィンドウウィンドウ リソース解放
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static void afwsub_ResRelease( AN_FONT_WIN* wk)
{
	GF_Disp_GX_VisibleControl( GX_PLANEMASK_BG1, VISIBLE_OFF );
	GF_BGL_PrioritySet( FLD_MBGFRM_EFFECT1, wk->bg_pri);

	GF_BGL_BmpWinOffVReq(&wk->win);
	GF_BGL_BmpWinDel(&wk->win);
	//スクリーンクリア
	GF_BGL_ScrClear( wk->fsys->bgl, FLD_MBGFRM_EFFECT1 );
	GF_BGL_ClearCharSet( FLD_MBGFRM_EFFECT1, ALF_WIN_CGX_SIZ*0x20, 0, wk->heapID );
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	アンノーン文字ウィンドウウィンドウ 明滅ウィンドウサブ
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static BOOL afwsub_InputSub( AN_FONT_WIN* wk)
{
	if(sys.trg & (PAD_BUTTON_DECIDE|PAD_BUTTON_DECIDE)){
		return TRUE;
	}
	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////////////////////
//T29ワタルのカイリュー空を飛ぶエフェクト
/////////////////////////////////////////////////////////////////////////////////////////////
typedef struct _WATARU_SORATOBI_DEMO{
	int	heapID;
	int	seq;

	FIELDSYS_WORK* fsys;
	POKEMON_PARAM *poke_param;
	FIELD_OBJ_PTR	fobj_wataru;
	FIELD_OBJ_PTR	fobj_kairyu;
	TCB_PTR tcb;
}WATARU_SORATOBI_DEMO;

static WATARU_SORATOBI_DEMO* wsdsub_WorkInit( FIELDSYS_WORK* fsys,
			FIELD_OBJ_PTR fobj_wataru,FIELD_OBJ_PTR fobj_kairyu);
static BOOL GMEVENT_WataruSoratobiDemo( GMEVENT_CONTROL* event );

//----------------------------------------------------------------------------------------------
/**
 *	@brief	T29ワタルのカイリュー空を飛ぶエフェクト
 *
 * @param	event		イベント制御ワークへのポインタ
 * @param	no			再生パターンナンバー
 *
 * @retval	none
 */
//----------------------------------------------------------------------------------------------
void EventCmd_WataruSoratobiDemo( GMEVENT_CONTROL* event ,
	FIELD_OBJ_PTR fobj_wataru,FIELD_OBJ_PTR fobj_kairyu)
{
	FIELDSYS_WORK* fsys	= FieldEvent_GetFieldSysWork( event );

	FieldEvent_Call( event, GMEVENT_WataruSoratobiDemo,
		wsdsub_WorkInit( fsys, fobj_wataru,fobj_kairyu));
	return;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	T29ワタルのカイリュー空を飛ぶエフェクト
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static WATARU_SORATOBI_DEMO* wsdsub_WorkInit( FIELDSYS_WORK* fsys,
			FIELD_OBJ_PTR fobj_wataru,FIELD_OBJ_PTR fobj_kairyu)
{
	WATARU_SORATOBI_DEMO* wk;

	//システムワーク確保
	wk = sys_AllocMemory( HEAPID_FIELD, sizeof(WATARU_SORATOBI_DEMO) );
	if( wk == NULL ){
		GF_ASSERT_MSG(0,"ワタルのカイリュー空を飛ぶ再生 メモリ確保失敗！\n");
		return NULL;
	}
	//初期化
	MI_CpuClear8( wk, sizeof(WATARU_SORATOBI_DEMO) );
	wk->fsys	= fsys;
	wk->fobj_wataru = fobj_wataru;
	wk->fobj_kairyu = fobj_kairyu;
	wk->heapID = HEAPID_FIELD;

	//カイリューパラメータ作成(レベルとか適当)
	wk->poke_param = PokemonParam_AllocWork(wk->heapID);
	PokeParaInit(wk->poke_param);
	PokeParaSet(wk->poke_param,MONSNO_KAIRYUU,100,POW_RND,RND_NO_SET,0,ID_NO_RARE,0);

	return wk;
}

//----------------------------------------------------------------------------------------------
/**
 *	@brief	T29ワタルのカイリュー空を飛ぶエフェクト
 *	@param	event		イベント制御ワークへのポインタ
 *
 *	@retval	"FALSE=継続、TRUE=終了"
 */
//----------------------------------------------------------------------------------------------
static BOOL GMEVENT_WataruSoratobiDemo( GMEVENT_CONTROL* event )
{
	WATARU_SORATOBI_DEMO* wk = FieldEvent_GetSpecialWork( event );

	switch(wk->seq){
	case 0:
		wk->tcb = FieldCutIn_Init_ModeWataru( wk->fsys,
					wk->poke_param,wk->fobj_wataru,wk->fobj_kairyu );
		wk->seq++;
		break;
	case 1:
		if( FieldCutIn_EndCheck(wk->tcb) == FALSE ){
			break;
		}
		FieldCutIn_End( wk->tcb );

		//メモリ解放
		sys_FreeMemoryEz(wk->poke_param);
		sys_FreeMemoryEz(wk);
		return TRUE;
	}
	return FALSE;
}

/////////////////////////////////////////////////////////////////////////////////////////////
//デバッグ機能
/////////////////////////////////////////////////////////////////////////////////////////////
#ifdef FIELD_DEMO_DEBUG
static void FieldDemoDebugStart( void )
{
	pFieldDemoDebugTcb = TCB_Add( FieldDemoDebugTcb, NULL, 0 );
}

static void FieldDemoDebugEnd( void )
{
	TCB_Delete( pFieldDemoDebugTcb );
}

static void FieldDemoDebugTcb( TCB_PTR tcb, void* p_work )
{
	// 動さ停止
	if( sys.tp_trg ){
		FIELD_DEMO_DEBUG_STOP ^= 1;

		OS_Printf( "停止:1 再生:0 %d\n", FIELD_DEMO_DEBUG_STOP );
	}

	// 値変更
	if( sys.cont & PAD_BUTTON_L ){
		if( sys.repeat & PAD_BUTTON_A ){
//			OS_Printf( "%d\n", );
		}
		if( sys.repeat & PAD_BUTTON_Y ){
//			OS_Printf( "%d\n", );
		}
	}
	if( sys.cont & PAD_BUTTON_R ){
		if( sys.repeat & PAD_BUTTON_A ){
//			OS_Printf( "%d\n", );
		}
		if( sys.repeat & PAD_BUTTON_Y ){
//			OS_Printf( "%d\n", );
		}
	}
	if( sys.cont & PAD_BUTTON_START ){
		if( sys.repeat & PAD_BUTTON_A ){
//			OS_Printf( "%d\n", );
		}
		if( sys.repeat & PAD_BUTTON_Y ){
//			OS_Printf( "%d\n", );
		}
	}
}
#endif // FIELD_DEMO_DEBUG